package com.integral.conf;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //1.创建Bean对象，需要自定义类
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //2. DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 关联userRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //3.shiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getshiroFilterFactory(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();

        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //设置shiro内置过滤器
        /**
         * anon: 无需认证即可访问
         * authc: 必须认证才能访问
         * user: 必须拥有记住我功能才能用
         * perms: 必须拥有对某个资源的权限才能访问
         * role: 拥有某个角色权限
         */

        //拦截
        Map<String,String> filter = new LinkedHashMap<>();
        //授权，正常情况下未授权跳转到未授权页面
        filter.put("/user/add","perms[user:add]");
        filter.put("/user/*","authc");

        bean.setFilterChainDefinitionMap(filter);

        //设置登录请求
        bean.setLoginUrl("/login");
        //设置未授权页面
        //bean.setUnauthorizedUrl("/noauth");

        return bean;
    }

    //整合 shiroDialect, 用来整合 shiro thymeleaf
    // 页面上直接动态的检测该用户是否拥有某个角色或者某个权限
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

    //鉴权可能用到以下代码
    /**
     *
     * @RequiresPermissions({"user:update:view"})//检查操作权限
     * @RequiresPermissions(value={"user:add","user:view"},logical=Logical.OR)//两个操作权限其中一个满足条件即可通过检查
     * @RequiresRoles({"admin"})//检查角色
     * @RequiresRoles(value={"debug","admin"},logical=Logical.OR)//两个角色其中一个角色满足条件即可
     *
     * @RequiresAuthentication//检查是否通过shiro认证
     * @RequiresGuest//不需要验证
     * @RequiresUser//检查用户是否是当前系统中的用户
     */

    /**
     * 开启Shiro注解支持（例如@RequiresRoles()和@RequiresPermissions()）
     * shiro的注解需要借助Spring的AOP来实现
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启AOP的支持
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor=new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}
